﻿using BoardGame;
using GameModelView;
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Drawing;
using System.Diagnostics;


namespace ChessWinControllerSpace
{
    static class Program
    {
        [STAThread]
        static void Main ()
        {
            Application.EnableVisualStyles ();
            Application.SetCompatibleTextRenderingDefault (false);
            Application.Run (new ChessWinController ());
        }
    }
 

    public partial class ChessWinView
    {
        static internal Icon[][] pieceIcon = new Icon[][]
        { new Icon[]
          { null,
            global::ChessWinControllerSpace.Properties.Resources.WhiteKing,
            global::ChessWinControllerSpace.Properties.Resources.WhiteQueen,
            global::ChessWinControllerSpace.Properties.Resources.WhiteRook,
            global::ChessWinControllerSpace.Properties.Resources.WhiteBishop,
            global::ChessWinControllerSpace.Properties.Resources.WhiteKnight,
            global::ChessWinControllerSpace.Properties.Resources.WhitePawn
          },
          new Icon[]
          { null,
            global::ChessWinControllerSpace.Properties.Resources.BlackKing,
            global::ChessWinControllerSpace.Properties.Resources.BlackQueen,
            global::ChessWinControllerSpace.Properties.Resources.BlackRook,
            global::ChessWinControllerSpace.Properties.Resources.BlackBishop,
            global::ChessWinControllerSpace.Properties.Resources.BlackKnight,
            global::ChessWinControllerSpace.Properties.Resources.BlackPawn
          }
        };

        private ChessWinController chessController;
        private ChessModelView chessGame;


        internal ChessWinView (ChessWinController winController, ChessModelView chessGame)
        {
            this.chessController = winController;
            SetChessGame (chessGame);
        }


        public void SetChessGame (ChessModelView chessGame)
        {
            if (chessGame == null)
                throw new ArgumentNullException ("chessGame");

            this.chessGame = chessGame;

            this.chessGame.GameCreated += ShowNewGame;
            this.chessGame.StatusUpdate += UpdateStatus;
            this.chessGame.TokenRemove += RemoveToken;
            this.chessGame.TokenPlace += PlaceToken;
            this.chessGame.MoveProcess += ProcessCompletedMove;
            this.chessGame.UndoPreview += RemoveMove;
            this.chessGame.HiliteChange += chessController.SetHilite;
            this.chessGame.HilitesClear += chessController.ClearHilites;

            ShowNewGame ();
            UpdateStatus ();
        }


        private void ShowNewGame ()
        {
            chessController.moveList.Items.Clear ();

            for (int y = 0; y < chessGame.Board.YSize; ++y)
                for (int x = 0; x < chessGame.Board.XSize; ++x)
                {
                    Piece piece = chessGame.Board[x, y] as Piece;
                    if (piece != null)
                        PlaceToken (x, y, piece.Side, piece.Token);
                    else
                        RemoveToken (x, y);
                }
        }


        private void UpdateStatus ()
        {
            chessController.promoList.Text = chessGame.CurrentPlayerPromotionName;
            string[] list = chessGame.GetStatus ();

            chessController.turn.Text = list[0];
            chessController.status1.Text = list[1];
            chessController.status2.Text = list[2];

            UpdateEnables ();
        }


        private void UpdateEnables ()
        {
            chessController.gameMenuResign.Enabled = chessGame.IsUnderway;
            chessController.gameMenuUndo.Enabled = chessGame.IsUnderway && chessGame.Plies.Count > 0;
            chessController.drawMenu.Enabled = chessGame.IsUnderway;
            chessController.drawMenuNoCaptures.Enabled = chessGame.IsUnderway && chessGame.Is50MoveRuleClaimable;
            chessController.drawMenuRepetitive.Enabled = chessGame.IsUnderway && chessGame.Same6Moves;
            chessController.drawMenuRequest.Enabled = chessGame.IsUnderway;

            chessController.promoList.Enabled = chessGame.IsUnderway;
        }


        private void RemoveToken (int x, int y)
        {
            chessController.SetIcon (x, y, null);
        }


        private void PlaceToken (int x, int y, Player player, Token token)
        {
            chessController.SetIcon (x, y, pieceIcon[(int) player][(int) token]);
        }


        private void ProcessCompletedMove ()
        {
            int lastItem;
            Ply ply = chessGame.Plies.Top;
            string newText = ply.ToString ();

            chessController.ClearSelection ();

            if (ply.Moving.Side == Player.Black)
            {
                lastItem = chessController.moveList.Items.Count - 1;
                string text = (string) chessController.moveList.Items[lastItem];
                chessController.moveList.Items[lastItem] = text + "  " + newText;
            }
            else
            {
                int turnNumber = chessGame.Plies.Count / 2 + 1;
                lastItem = chessController.moveList.Items.Count;
                chessController.moveList.Items.Add (turnNumber.ToString () + ".  " + newText);
            }

            chessController.moveList.Focus ();
            chessController.moveList.SetSelected (chessController.moveList.Items.Count - 1, true);
        }


        private void RemoveMove ()
        {
            int lastItem = (chessGame.Plies.Count - 1) / 2;
            if (chessGame.Plies.Count % 2 == 0)
                chessController.moveList.Items[lastItem] = (lastItem + 1).ToString () + ".  " + chessGame.Plies[chessGame.Plies.Count - 2].ToString ();
            else
                chessController.moveList.Items.RemoveAt (lastItem);
        }
    }
}
